<template>
    <div>组件设置</div>
    <div>
        <el-button @click="editAttribute">改变height属性</el-button>
        <el-button @click="generateDSL">测试DSL到ast的转换</el-button>
    </div>
</template>

<script lang="ts" setup>
    import {useRenderTreeStore} from '@/store/renderTree'
    import emitter from '@/utils/emitter'
    import {ref,reactive } from 'vue'
    // import { ElMessage } from 'element-plus'

    /**
     * 该页面思路：
     * 本质是通过发布订阅者模式来更新渲染树的数据
     * ——1.获取存储在store中的componentId可以知道修改的是哪个组件
     * ——2.通过发布订阅者模式，发布消息。
     * ——3.首页和相应的组件接收到消息后，首页更新渲染树数据treeArr并重新赋值，组件内部接收后对组件设置区修改的属性重新赋值和回显
     */
    const store=useRenderTreeStore();
    const editAttribute=()=>{
        if(!store.componentId){
            ElMessage('请选择组件！')
            console.log('hhhhh')
            return false;
        }
        console.log('组件id',store.componentId)
        //修改的属性，eg:修改按钮的文本,后续会根据componentId来修改，componentId在渲染区点击时就已经保存在store中
        const props:PropMap={
            'text':{
                name:'text',
                propType:'string',
                default:'按钮',
                title:'按钮文本',
                text:'显示在按钮上的文字',
                required:true
            }
        }
        const props_attribute:string='text'
        store.editProps(props,props_attribute)
        console.log('组件设置区---',`component:update:${store.componentId}`)
        //通知首页
        emitter.emit('getMessage', '信息：改变了属性')
        //通知需要改变的组件
        emitter.emit(
            `component:update:${store.componentId}`,
            {
                props:props,
                props_attribute:props_attribute,
            }
        )
    }

    /**
     * 代码生成：
     * 1.将DSL转成@vue/compiler-core所需要的AST语法树
     * 2.将AST转成vue3所需要的渲染函数（纯字符串形式），便于获取相关数据
     * 3.将数据引入到固定的模板字符串中
     *  ——方案（各种主流方案）
     *      1.字符串模板拼接
     *      2.使用模板引擎，采用固定的模板
     *      3.字符串模板拼接和模板引擎混合使用
     *      4.采用babel的AST语法树转换
     * ——最终方案：使用方案1+方案4（方便后期的复杂逻辑转换和拓展，方案2和方案3无法支持过多的逻辑故抛弃）
     *     ——原因
     *          1.DSL中存在逻辑节点，表示条件逻辑/循环逻辑等，对于逻辑部分，可采用babel的AST转换，因为使用babel更加方便，
     *            同时也避免单纯使用模板字符串无法避免的引号嵌套的问题，逻辑节点还存在嵌套的逻辑节点等
     *          2.对于template部分，可以采用递归循环的方法，将所涉及到的标签提取出来，然后组成一个字符串
     *            对于script部分，则采用1步骤，同时其中的ref/reactive定义变量，则与组件中涉及到的props的属性来决定,这种动态的props属性通常都是变量，需要改变的
     *            对于样式style部分，同样采用模板字符串拼接的方式，将DSL中涉及到的style提取出来，最后生成一个style的字符串
     *          3.将template部分生成的字符串，script部分生成的字符串，style部分生成的字符串，都提取出来，然后定义一个模板，将三个字符串赋值上去
     *          4.嘴周会得到一个模板的vue3代码
     */
    const generateDSL=()=>{
        console.log('generate-----')
        let testDSL:ComponentMeta[]=[
            {
                id: '1',
                type: 'Linelayout',
                componentName: 'div',
                currentComponent: undefined,
                title: '线性布局',
                group: 'Layout',
                props: {
                    'text': {
                        name: 'text', // 修正：设为合法属性名（原空字符串）
                        propType: 'string', // 修正：符合联合类型（原空字符串）
                        default: '',
                        title: '文本内容', // 补充：原空字符串，提升可读性
                        text: '',
                        required: true,
                    }
                },
                children: [
                    {
                        id: '1-1',
                        type: 'Button',
                        componentName: 'el-button',
                        currentComponent: undefined,
                        title: '按钮',
                        group: 'Display',
                        props: {
                            'text': {
                                name: 'text',
                                propType: 'string',
                                default: '按钮',
                                title: '按钮的文本',
                                text: '文本内容',
                                required: true,
                            },
                            'type': {
                                name: 'type',
                                propType: 'string',
                                default: 'primary',
                                title: '按钮类型',
                                text: 'primary',
                                required: true,
                            }
                        },
                        children: [],
                        slots: {},
                        events: {},
                        logic: {
                            type: 'Condition',
                            trigger: 'click',
                            test: 'testField=="111"',
                            consequent: {
                                props: {
                                    'disabled': {
                                        name: 'disabled',
                                        propType: 'boolean',
                                        default: false,
                                        title: '是否禁用',
                                        text: 'false', // 修正：text 设为字符串（或布尔值，需统一类型）
                                        required: false
                                    }
                                },
                                events: {
                                'click': { handler: 'handleDelete' } // 符合扩展后的 EventHandler 类型
                                }
                            },
                            alternate: {
                                props: {
                                    'type': {
                                        name: 'type',
                                        propType: 'string',
                                        default: 'primary',
                                        title: '类型',
                                        text: 'danger',
                                        required: false
                                    },
                                    'disabled': {
                                        name: 'disabled',
                                        propType: 'boolean',
                                        default: false,
                                        title: '是否禁用',
                                        text: 'true', // 修正：text 设为字符串（与 default 布尔值对应）
                                        required: false
                                    }
                                }
                            }
                        }
                    }
                ],
                slots: {},
                events: {}
            },
            {
                id: '2',
                type: 'Button',
                componentName: 'el-button',
                currentComponent: undefined,
                title: '按钮',
                group: 'Display',
                props: {
                    'text': {
                        name: 'text',
                        propType: 'string',
                        default: '按钮',
                        title: '按钮的文本',
                        text: '文本内容',
                        required: true,
                    },
                    'type': {
                        name: 'type',
                        propType: 'string',
                        default: 'primary',
                        title: '按钮类型',
                        text: 'primary',
                        required: true,
                    },
                    'disabled': {
                        name: 'disabled',
                        propType: 'boolean',
                        default: false,
                        title: '是否禁用',
                        text: 'false', // 修正：text 设为字符串（或布尔值，需统一类型）
                        required: false
                    }
                },
                children: [],
                slots: {},
                events: {},
            }
        ]
        generateTemplate(testDSL);
    }
    //生成单个组件的templateb部分
    const parseComponents=(component:ComponentMeta)=>{
        let template_single='';
        let tag=component.componentName; //组件的标签
        let prop_content='';//组件的props的内容
        let text='';//组件的文本
        for(let key in component.props){
            if(key=='text'){
                text=component.props[key].text? component.props[key].text :component.props[key].default
            }else{
                switch(component.props[key].propType){
                    case 'string':
                        prop_content=prop_content+`:${key}="${component.props[key].text}"`
                        break;
                    case 'number':
                        prop_content=prop_content+`:${key}=${component.props[key].text}`
                        break;
                    case 'boolean':
                        if(component.props[key].text=='true'){
                            prop_content=prop_content+`:${key}="true"`
                        }else if(component.props[key].text=='false'){
                            prop_content=prop_content+`:${key}="false"`
                        }
                        break;
                }
            }
        }
        template_single=`<${tag} ${prop_content}>${text}</${tag}>`;
        return template_single;
    }
    //生成template部分
    const generateTemplate=(dsl:ComponentMeta[])=>{
        let templateStr='';
        dsl.forEach((item,index)=>{
            let single= parseComponents(item);
            console.log('-----single',single)
        })
    }
</script>